<?php
/**
 * *********************************************************************************************************************
 * 申通代收货款通知接口（对接深圳 闵思达 MSD）
 * *********************************************************************************************************************
 */
namespace soa\parter\sto;

use artisan\cache;
use artisan\http;
use soa\partner\partnerCommon;

class CashOnDelivery
{
    /**
     * 服务地址
     * @var string
     */
//    protected $service_url = 'http://222.66.109.134:22226/stoPlatform/cod/codOperate!codQuery.action';  //测试地址
//    protected $service_url = 'http://222.66.39.203:22221/stoPlatform/cod/codOperate!codQuery.action';  //正式地址
    protected $service_url = 'http://stokb.sto-express.cn:22226/codoperate/cod/codOperate!codQuery.action';  //正式地址新

    /**
     * 公司名称
     */
    protected $company_id = 'kbwl';

    /**
     * 传输校验的key值
     * @var string
     */
    protected $key = 'VGxkSmNtTnFWbWhPYlZFOQ==';

    /**
     * 消息类型
     * @var string
     */
    protected $msg_type = 'CODQUERY';

    /**
     * 获取服务ID
     * @return string
     */
    public function getCompanyId()
    {
        return $this->company_id;
    }

    /**
     * 获取服务地址
     * @return string
     */
    public function getServiceUrl()
    {
        return $this->service_url;
    }

    /**
     * 获取校验key
     * @return string
     */
    public function getKey()
    {
        return $this->key;
    }

    /**
     * 获取消息类型
     * @return string
     */
    public function getMsgType()
    {
        return $this->msg_type;
    }

    /**
     * 获取代收货款列表
     * @param $cmPhone
     * @param $data
     * @return array|string
     * {"logisticProviderId": "STO","success": "true","reason": "","responseItems": [{"success": "true","reason": "","billCode": "113000560808","codAmount": "250.50"}, {"success": "false","reason": "S10","billCode": "33100003050082","codAmount": ""}]}
     */
    public function getCODList($cmPhone,$data)
    {
        $datas = [
            'eccompanyid'  =>  $this->getCompanyId(),
            'cods'          =>  $data,
        ];

        $t1=time();
        if($data){
            $tmpResult = $this->requestApi($datas);
//            logDebug($tmpResult,'cod_result_sto',true);
        }
        $result=[];
        if(empty($tmpResult)) {
            logDebug('获取申通货款信息返回结果为空' . json_encode($data, JSON_UNESCAPED_UNICODE), 'COD_debug', (time()-$t1).':'.$cmPhone);
        } else {
            $result = json_decode($tmpResult, true);

            if(json_last_error() ==0) {
                if($result['success'] == 'true') {
                    $return = [];
                    foreach ($result['responseItems'] as $val) {
                        if ($val['success'] == 'true') {
                            $return[$val['billCode']] = [
                                'waybill_no' => $val['billCode'],
                                'payment'    => $val['codAmount'],
                                'is_pay'     => 0,  //0代收1是到付
                            ];
                        }
                    }
                    unset($data,$datas,$cmPhone,$result);
                    return $return;
                } elseif($result['success'] == 'false') {
                    $error = $this->getError($result['reason']);
                    logDebug('获取申通货款信息失败' . $result['reason'] . $error . json_encode($data, JSON_UNESCAPED_UNICODE), 'COD_debug',(time()-$t1).':'.$cmPhone);
                }
            }else {
                logDebug('获取申通货款信息请求超时:请求参数:' . json_encode($data, JSON_UNESCAPED_UNICODE).' 返回值:'.$tmpResult, 'COD_debug',(time()-$t1).':'.$cmPhone,true);
            }
            //logDebug($tmpResult, 'COD_result',(time()-$t1));
        }

        if($data){
            //失败重新入缓存
            $accessInfo = partnerCommon::getAccessInfo(['brand'=>'sto','username'=>$cmPhone]);
            if($accessInfo['cm_code']) {
                $tmp = [];
                foreach($data as $v){
                    $tmp[$v['billCode']] = $v['billCode'];
                }
                $key = 'COD_PI:sto:'.$accessInfo['cm_code'].':'.date('Y-m-d');
                cache::connect('pda')->hMset($key, $tmp);
            }

        }
        unset($data,$datas,$cmPhone);
        return $result['reason']?:null;
    }

    /**
     * 发送请求
     * @param $data
     * @return mixed
     */
    public function requestApi($data)
    {
        $data = mb_convert_encoding(json_encode($data), 'UTF-8');             //转UTF-8
//        $data = json_encode($data);
        $data_digest = (base64_encode(md5($data . $this->getKey())));  //签名       签名方式 base64(md5(data字段+key))
        $param = array(
            'logistics_interface' => $data,                   //数据
            'data_digest'          => $data_digest,            //签名
            'msg_type'             => $this->getMsgType(),     //接口类型
            'eccompanyid'          => $this->getCompanyId(),   //电商id
        );

        $option = array('TIMEOUT'=>2);
//        echo json_encode($param);
        return http::post($this->getServiceUrl(),$param,$option);
    }

    /**
     * 错误原因
     * @param $errorNo
     * @return mixed
     */
    public function getError($errorNo)
    {
        switch($errorNo){
            case 'S01':
                $errorType = 'logistics_interface数据不符合JSON格式标准';
                break;
            case 'S02':
                $errorType = 'data_digest签名不正确，没有通过校验';
                break;
            case 'S03':
                $errorType = 'logisticproviderid物流公司代码在配送系统没有维护或者匹配不到（大小写敏感）';
                break;
            case 'S04':
                $errorType = '消息推送类型msg_type的值内容不在文档规定的范围内';
                break;
            case 'S05':
                $errorType = '跟踪推送信息中logistics_interface中内容格式不正确';
                break;
            case 'S06':
                $errorType = '创建订单时如果30秒内未获得响应认为是超时';
                break;
            case 'S07':
                $errorType = '数据库异常或其它系统错误';
                break;
            case 'S08':
                $errorType = 'eccompanyid错误（大小写敏感）';
                break;
            case 'S09':
                $errorType = '运单编号错误（不符合申通单号规则）';
                break;
            case 'S10':
                $errorType = '系统未找到相对应的结果集（不存在该代收货款单号）';
                break;
            default:
                $errorType = '';
        }
        return $errorType;
    }
}